test: resolve challenge records through the mock, and check that it happened - #1144
Open
kvinwang wants to merge 1 commit into
Open
test: resolve challenge records through the mock, and check that it happened#1144kvinwang wants to merge 1 commit into
kvinwang wants to merge 1 commit into
Conversation
…appened
certbot resolves each challenge name itself before telling the CA to look, so
that a record which has not propagated is reported by name rather than as an
order failure. Nothing in the suite exercised that: the gateway resolved
through Docker's embedded DNS, which has never heard of the test zones, so
every self-check ran its full budget, warned, and proceeded -- for dns-01 too,
seconds after certbot itself wrote the record.
WARN no authoritative nameserver for _acme-challenge.test0.local,
using the system resolver
DEBUG challenge not found, waiting for 500ms tries=2 max_wait=30s
Pointing the gateways at the mock needs the mock to stop being a black hole for
everything else: a name it does not know was answered NOERROR with no records,
which a resolver reads as authoritative and does not retry elsewhere, so the
gateway would lose the other containers. It now forwards those upstream, which
is what makes it usable as a client's only resolver rather than only as a CA's
`-dnsserver`.
The check is advisory, so nothing downstream reveals whether it worked -- an
order succeeds either way. The mock therefore logs every question it is asked
and serves them at /api/dns-queries, and the two cases are asserted directly:
- Answered, for a record the suite published. Observed rather than triggered:
the periodic renewal picks a domain up as soon as it is added, so forcing one
races it and can find nothing left to do.
- Asked repeatedly and never answered, for a name with no record. Polling is
the point -- a record may still be propagating -- and giving up must not stop
the order.
Each keys off a name nothing else asks for, so they need no clearing and do not
depend on running in any order.
Incidentally the suite gets its time back: a self-check that resolves settles
in seconds instead of spending the whole advisory wait on every order.
kvinwang
force-pushed
the
feat/certbot-dns-persist-01
branch
from
August 26, 2026 08:35
9e30e53 to
5ed087c
Compare
kvinwang
force-pushed
the
feat/e2e-resolve-challenge-records
branch
from
August 26, 2026 08:35
a23d0a4 to
354f9f5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
certbot resolves each challenge name itself before telling the CA to go and
look, so a record that has not propagated is reported by name instead of as an
order failure. The E2E suite never exercised it.
The gateway resolved through Docker's embedded DNS, which has never heard of
the test zones. So every self-check ran its full budget, warned, and proceeded
— for
dns-01too, seconds after certbot itself had written the recordthrough the mock's Cloudflare API:
Only Pebble read the mock's DNS, via
-dnsserver. Everything the client doeswith DNS — the authoritative-nameserver discovery, the retry loop, the advisory
timeout — was covered in its failure path only, and every order paid the full
wait for nothing.
Fix
The mock forwards what it does not own. A name outside its zones was
answered
NOERRORwith no records, which a resolver reads as an authoritative"no such record" and does not retry elsewhere — so a client pointed here as its
only resolver would lose the other containers. Those questions now go upstream,
which is what makes it a resolver rather than only a CA's
-dnsserver.The gateways use it. One
dns:entry per gateway service.The mock says what it was asked. The check is advisory, so an order
succeeds whether or not it worked and nothing downstream reveals which. Every
question is logged and served at
/api/dns-queries.Cases
periodic renewal picks a domain up as soon as it is added, so forcing one
races it and can find nothing left to do.
the point, and giving up must not stop the order.
Each keys off a name nothing else asks for, so they need no clearing and do not
depend on ordering.
Verification
Full suite, this branch vs its base, same host:
feat/certbot-dns-persist-01)The two new passes are the two new cases; the 22 failures are identical and
pre-existing on this host, all in the proxy/TLS phases — the container resolver
inherits the host's search domain, so
_dstack-app-address-wildcard.<name>islooked up under it, and RA-TLS peering reports
peer certificate does not contain app_id. Neither is touched here.A self-check that resolves now settles in seconds instead of spending the whole
advisory wait, so the suite gets that time back on every order.
Base
Stacked on #1132, which is where the DNS-capable mock and the gateway suite's
use of it come from. Merge that first.